package com.github.linkoog.model_designer.ide.editer.dbtable.right_editer;

import com.github.linkoog.model_designer.ide.type.TableYamlFileType;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.FileEditorManagerListener;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileManager;
import com.intellij.openapi.vfs.newvfs.BulkFileListener;
import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
import com.intellij.ui.JBSplitter;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.JBDimension;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;
import java.awt.*;
import java.util.List;

public class DBTableRightPanelInjector implements FileEditorManagerListener, BulkFileListener {

    private Project project;

    public DBTableRightPanelInjector(Project project){
        this.project = project;
        MessageBusConnection messageBusConnection = project.getMessageBus().connect(project);
        messageBusConnection.subscribe(FileEditorManagerListener.FILE_EDITOR_MANAGER, this);
        messageBusConnection.subscribe(VirtualFileManager.VFS_CHANGES, this);
    }

    /**
     *   文件打开后，注入右侧可视化面板
     */
    @Override
    public void fileOpened(@NotNull FileEditorManager fileEditorManager, @NotNull VirtualFile virtualFile) {
        if (!(virtualFile.getFileType() instanceof TableYamlFileType)){
            return;
        }


        FileEditor[] fileEditors = fileEditorManager.getEditors(virtualFile);
        for (FileEditor fileEditor : fileEditors) {
            if (!(fileEditor instanceof TextEditor)){
                continue;
            }

            inject(fileEditor);
        }
    }

    /**
     *   文件编辑后，保存时更新右侧可视化面板
     */
    @Override
    public void after(@NotNull List<? extends @NotNull VFileEvent> events) {
        for (VFileEvent event : events) {
            final VirtualFile virtualFile = event.getFile();
            if (!event.isFromSave() || virtualFile == null ||  !(virtualFile.getFileType() instanceof TableYamlFileType)){
                continue;
            }

            final DBTableRightPanel dbTableLeftPanel = virtualFile.getUserData(DBTableRightPanel.DB_TABLE_RIGHT_PANEL_KEY);
            if ( dbTableLeftPanel == null){
                continue;
            }

            dbTableLeftPanel.resetPanelContext();
            break;
        }
    }

    private JPanel getPanel(FileEditor editor) {
        try {
            JPanel outerPanel = (JPanel)editor.getComponent();
            BorderLayout outerLayout = (BorderLayout)outerPanel.getLayout();
            Component layoutComponent = outerLayout.getLayoutComponent(BorderLayout.CENTER);

            if (layoutComponent instanceof JBSplitter) {
                // editor is inside firstComponent of a JBSplitter
                JBSplitter jbSplitter = (JBSplitter) layoutComponent;
                JPanel editorComp = (JPanel)jbSplitter.getFirstComponent();
                BorderLayout editorLayout = (BorderLayout)editorComp.getLayout();
                layoutComponent = editorLayout.getLayoutComponent(BorderLayout.CENTER);
            }

            JPanel panel;
            JLayeredPane pane = (JLayeredPane)layoutComponent;
            if (pane.getComponentCount() > 1){
                panel = (JPanel)pane.getComponent(1);
            } else {
                panel = (JPanel) pane.getComponent(0);
            }

            // Assert ahead of time that we have the expected layout, so the caller dosent need to
            BorderLayout borderLayout = (BorderLayout)panel.getLayout();
            return panel;
        } catch (ClassCastException e) {
            e.printStackTrace();
            return null;
        }
    }

    private void inject(FileEditor editor) {
        JPanel contextPanel = getPanel(editor);
        if (contextPanel == null){
            return;
        }

        BorderLayout innerLayout = (BorderLayout)contextPanel.getLayout();
        Component centerComponent = innerLayout.getLayoutComponent(BorderLayout.CENTER);
        if (centerComponent != null){
            // 左右分割面板
            Splitter splitter = new Splitter(false, 0.32F);
            splitter.setResizeEnabled(true);
            splitter.setDividerPositionStrategy(Splitter.DividerPositionStrategy.KEEP_FIRST_SIZE);

            centerComponent.setMinimumSize(new JBDimension(300, -1));
            splitter.setFirstComponent((JComponent)centerComponent);

            DBTableRightPanel leftPanel = new DBTableRightPanel(project, editor.getFile());
            splitter.setSecondComponent(leftPanel.getMyMainPanel());

            contextPanel.add(splitter, BorderLayout.CENTER);
        }
    }

}
